// DisplayLine.h: interface for the CDisplayLine class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_DISPLAYLINE_H__976DAECB_17FA_456E_B41A_85EF6A33CCB0__INCLUDED_)
#define AFX_DISPLAYLINE_H__976DAECB_17FA_456E_B41A_85EF6A33CCB0__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define	DL_TIMER_CURSOR	101

enum
{
	//for text align
	TEXT_ALIGN_MODE_NONE	=	0,

	TEXT_ALIGN_MODE_LEFT,
	TEXT_ALIGN_MODE_MIDDLE,
	TEXT_ALIGN_MODE_RIGHT,

	//for text compact
	TEXT_COMPACT_MODE_NONE	=	0,

	TEXT_COMPACT_MODE_NOSPACE,
};

enum
{
	DISLINE_REFRESH_ALL		=	0,

	DISLINE_REFRESH_ALL_TEXT,
	DISLINE_REFRESH_NEW_TEXT,
};

enum
{
	CURSOR_STATE_NONE		=	0,

	CURSOR_STATE_VANISH,

	CURSOR_STATE_DISPLAY,
};

typedef CPoint	CCharLinePos;		//x for char, y for line, direction is same as bmp
typedef CSize	CCharLineSize;		//cx for char, cy for line
typedef CRect	CCharLinePosRange;	//topleft for start CCharLinePos, bottomright for end CCharLinePos

class CBufferLine;

//layout:
//client:	client.cx=wnd.clientarea.cx, client.cy=wnd.clientarea.cy
//font:		char.wd= wnd.font.extent("WWWW").cx/4, line.ht=wnd.font.extent("WWWW").cy
//size:		c=client.cx/char.wd, l=client.cy/line.ht
//display:	wd=c (chars), ht=l (lines)
//			tl={0,0}, rb={c-1, l-1}
//valid:	wd=c (chars), ht=l-1 (lines)
//			tl={0,0}, rb={c-1, l-2}
//input:	wd=c (chars), ht=1 (lines)
//			tl={0,l-1}, rb={c-1, l-1}
//buffer:	wd=-1, ht=-1 (UserDefined)
//			idx=0~buf.line-1
//cur:		wd=c (chars), ht=l-1 (lines)
//			tl={0,buf.line-l+1}, rb={buf.char-1,buf.line-1}
//new:		wd=-1, ht=-1
//			tl={0,}, rb={append.char-1, append.line-1}

class CDisplayLine  
{
public:
	CDisplayLine();
	virtual ~CDisplayLine();

//attributes
private:
	bool	m_bRefreshing;
	bool	m_bDrawing;
	bool	m_bAppendline;

protected:
	//for margin
	CRect	m_rectPanel;	//default = src. wnd.'s client
	CRect	m_rectOffset;	//default = {0}

	//for scaling
	double	m_dScaleX;	//default = 1.
	double	m_dScaleY;	//default = 1.

	//for memory DC and compatible
	CSize	m_bmpSize;	//triple of visible area
	CBitmap*	m_pBmpBack;	//following objects need to free manually
	CBitmap*	m_pBmpText;
	CBitmap*	m_pBmpFloat;
	CDC*		m_pDC;

	//for layout
	CCharLineSize		m_clszClient;	//x=wnd.client.cx/char.wd, y=wnd.client.cy/line.ht, default = {80,25}

	//for lines
	CCharLinePos	m_clptCur;	//current position, default = {0}
	CCharLinePos	m_clptNew;	//new position, default = {0}

	//for scrollbar
	BOOL			m_bAutoHorzScroll;	//default = TRUE
	BOOL			m_bAutoVertScroll;	//default = TRUE
	CCharLineSize	m_clszScrollGrid;	//amount of a grid for horz. and vert. respective, default = {1}
	CCharLineSize	m_clszScrollPage;	//amount of a page for horz. and vert. respective, default = {5}
	CCharLineSize	m_clszScrollWheel;	//amount of mouse wheel for horz. and vert. respective, default = {3}

	//for cursur
	BOOL		m_bCursorAlwaysFirst;	//default = FALSE
	BOOL		m_bCursorPaused;	//default = FALSE;
	CSize		m_szCursor;	//size of cursor, default = (2, char-width)
	CPoint		m_ptCursor;		//cursor position, default = {0}
	int			m_iCursorFreq;	//counts of flashing per ms, default = 1000
	int			m_iCursorState;	//default = 0
	BOOL		m_bCursorRight;	//default = FALSE
	BOOL		m_bUseBmpCursor;	//default = FALSE
	CBitmap*	m_pBmpCursor;	//default = NULL

	//for prompt
	BOOL		m_bUsePrompt;	//default = TRUE
	char*		m_strPrompt;	//default = "> "
	BOOL		m_bUsePromptFmt;	//default = FALSE
	char*		m_strPromptFmt;	//default =NULL
	COLORREF	m_clrPromptBack;	//default = bg color
	COLORREF	m_clrPromptText;	//default = text color

	//for tab / non-graph chars
	CCharLineSize	m_clszTab;	//x for char, y for line, default = (4,0)

	//for selection
	BOOL		m_bSelected;	//default = FALSE
	CCharLinePosRange	m_clprSelection;	//start and end positions of (char, line), default = {0}
	COLORREF	m_clrSelBack;	//background for selection, default = invert of bg color
	COLORREF	m_clrSelText;	//text for selection, default = invert of text color

	//for font
	char*	m_strFontFace;	//default = Arial, can be replaced for customization
	CFont*	m_pFont;	//default = NULL, can be replaced for customization

	//for background
	COLORREF	m_clrBack;	//default = black

	//for all texts
	COLORREF	m_clrText;	//default = white
	int			m_iTextAlign;	//align mode, default = left
	int			m_iTextCompact;	//compact mode, default = none

	//for one line
	BOOL	m_bLineWrap;	//default = FALSE, have h. scrollbar
	int		m_iLineWidth;	//default = -1, no limited
	int		m_iLineHeight;	//default = char height
	CRect	m_rectLineExt;	//relative the line origin size, negative for intent, default = {0}

	//for one char
	BOOL	m_bCharFull;	//default = FALSE
	int		m_iCharWidth;	//default = 8
	int		m_iCharHeight;	//default = 16
	CRect	m_rectCharExt;	//relative the char origin size, negative for intent, default = {0}
	int		m_iChineseWidth;	//default = double char width
	int		m_iChineseHeight;	//default = char height

	//for ext. buffer of lines
	CBufferLine*	m_pBufLines;	//default = generic, can be replaced for customizated class derived from CBufferLine

	//for ext. editor
	BOOL	m_bUseExtEdit;	//default = FALSE
	CWnd*	m_pExtEdit;		//default = NULL

public:

//operators
protected:

public:
	BOOL	CursorPaused() {return m_bCursorPaused;};

	int		CursorFreq() {return m_iCursorFreq;};

	void	EnableCursor(BOOL bEnable = TRUE, int iFreq = 1000);

	void	EnablePrompt(BOOL bEnable = TRUE) {m_bUsePrompt = bEnable;};

	int		LineChars() {return m_clszClient.cx;};

	int		MaxLines();
	int		PatchLines();
	int		UsedLines();
	int		RealLines();

//functions
protected:
	BOOL	DestroyMemoryDC();

	BOOL	PrepareInit();
	BOOL	PrepareDraw();

	BOOL	Refresh(int rflag = DISLINE_REFRESH_ALL);

	BOOL	StartCursor();
	BOOL	StopCursor();

public:
	BOOL	Destroy();

	BOOL	PauseCursor(BOOL bEnable = TRUE);
	BOOL	FlashCursor(CWnd* pWnd);

	BOOL	Resize(int cx, int cy);

	BOOL	Clear();

	BOOL	PrepareDC(CDC* pDC);

//overloads
protected:

public:
	BOOL	Init(CWnd* pWnd, CRect& rect);

	BOOL	AppendLine(char* strLine, int len = -1, BOOL bHeadPrompt = FALSE, BOOL bRefresh = TRUE);
	BOOL	PushLine(char* strLine, int len = -1);

//overrides
protected:

public:

//virtuals
protected:

public:
	virtual	BOOL	Draw(CWnd* pWnd, CRect* pRect = NULL);
	virtual	BOOL	Draw(CDC* pDC, CRect* pRect = NULL);

	virtual	BOOL	Input(CWnd* pWnd, char* strInput = NULL, int len = -1, BOOL bErase = FALSE, COLORREF clrText = RGB(255, 255, 255), COLORREF clrBack = RGB(0, 0, 0));
	virtual	BOOL	Input(CDC* pDC, char* strInput = NULL, int len = -1, BOOL bErase = FALSE, COLORREF clrText = RGB(255, 255, 255), COLORREF clrBack = RGB(0, 0, 0));

	virtual	BOOL	Cursor(CWnd* pWnd, COLORREF clrVanish = RGB(0, 0, 0), COLORREF clrDisplay = RGB(255, 255, 255));
	virtual	BOOL	Cursor(CDC* pDC, COLORREF clrVanish = RGB(0, 0, 0), COLORREF clrDisplay = RGB(255, 255, 255));

//statics
protected:

public:
};

#endif // !defined(AFX_DISPLAYLINE_H__976DAECB_17FA_456E_B41A_85EF6A33CCB0__INCLUDED_)
